﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms.Design;
using System.Security.Permissions;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;

namespace ControlsLib
{
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    class DataFormControlDesigner : ParentControlDesigner
    {
        #region Storage

        private DataFormControl _MBP;
        private DesignerVerbCollection _Verbs;

        #endregion

        #region Overrides

        public override void Initialize(IComponent component)
        {
            _MBP = component as DataFormControl;

            base.Initialize(component);
        }

        public override DesignerVerbCollection Verbs
        {
            get
            {
                if (_Verbs == null)
                {
                    _Verbs = new DesignerVerbCollection();
                    _Verbs.Add(new DesignerVerb("Choose Type", AddElements));
                }
                return _Verbs;
            }
        }

        #endregion

        #region " Private methods "

        private void AddElements(object sender, EventArgs e)
        {
            IDesignerHost DH = (IDesignerHost)GetService(typeof(IDesignerHost));
            if (DH != null)
            {
                DesignerTransaction DT = null;

                try
                {
                    DT = DH.CreateTransaction("Choosing Type");

                    Control.ControlCollection OldControls = _MBP.Controls;
                    RaiseComponentChanging(TypeDescriptor.GetProperties(typeof(Control))["Controls"]);

                    AssemblyTypePicker atp = new AssemblyTypePicker();
                    if (atp.ShowDialog() == DialogResult.OK)
                    {
                        //BindingSource bs = new BindingSource();
                        this._MBP.Container.Add(_MBP.m_bindingSource);

                        object OldDatasource = _MBP.m_bindingSource.DataSource;
                        RaiseComponentChanging(TypeDescriptor.GetProperties(typeof(BindingSource))["Datasource"]);

                        _MBP.AssemblyPath = atp.AssemblyPath;

                        if (atp.SelectedType != null)
                        {
                            _MBP.CurrentObject = Activator.CreateInstance(atp.SelectedType);

                            _MBP.m_bindingSource.DataSource = atp.SelectedType;

                            int step = 5;
                            int leftOffset = 5;
                            DataFormControlHelper dfch = new DataFormControlHelper(DH, _MBP.m_bindingSource);
                            foreach (System.Reflection.PropertyInfo pi in atp.SelectedType.GetProperties())
                            {
                                //Label l = new Label();
                                Label l = DH.CreateComponent(typeof(Label)) as Label;
                                l.Location = new System.Drawing.Point(leftOffset, step);
                                l.Text = string.Format("{0}:", pi.Name);

                                //TextBox txt = new TextBox();
                                Control txt = dfch.GetSpecificControl(pi.PropertyType);
                                txt.Location = new System.Drawing.Point(leftOffset + l.Width + 5, step);

                                // DataBinding...
                                ControlBindingsCollection OldDataBindings = txt.DataBindings;
                                RaiseComponentChanging(TypeDescriptor.GetProperties(typeof(Binding))["DataBindings"]);
                                txt.DataBindings.Add(new Binding("Text", _MBP.m_bindingSource, pi.Name));
                                RaiseComponentChanged(TypeDescriptor.GetProperties(typeof(Binding))["DataBindings"], OldDataBindings, txt.DataBindings);

                                //
                                step += l.Size.Height;

                                //
                                _MBP.Controls.Add(l);
                                _MBP.Controls.Add(txt);

                            }


















                            //ControlBindingsCollection OldDataBindings = null;
                            //DataFormControlHelper dfch = new DataFormControlHelper(DH, _MBP.m_bindingSource);
                            //dfch.ControlAdding += (s, e1) =>
                            //{
                            //    OldDataBindings = e1.Control.DataBindings;
                            //    RaiseComponentChanging(TypeDescriptor.GetProperties(typeof(Binding))["DataBindings"]);
                            //};

                            //dfch.ControlAdded += (s, e1) => {
                            //   RaiseComponentChanged(TypeDescriptor.GetProperties(typeof(Binding))["DataBindings"], OldDataBindings, e1.Control.DataBindings);
                            //};

                            //dfch.LoadProperties(atp.SelectedType, _MBP.Controls);
                        }

                        RaiseComponentChanged(TypeDescriptor.GetProperties(typeof(BindingSource))["Datasource"], OldDatasource, _MBP.m_bindingSource.DataSource);
                    }

                    RaiseComponentChanged(TypeDescriptor.GetProperties(typeof(Control))["Controls"], OldControls, _MBP.Controls);
                    
                    //Control.ControlCollection OldControls = _MBP.Controls;

                    //RaiseComponentChanging(TypeDescriptor.GetProperties(typeof(Control))["Controls"]);
                    //MyButton NewButton = DH.CreateComponent(typeof(MyButton)) as MyButton;
                    //NewButton.Text = NewButton.Name;
                    //_MBP.Controls.Add(NewButton);
                    //_MBP.Controls.SetChildIndex(NewButton, 0);
                    //RaiseComponentChanged(TypeDescriptor.GetProperties(typeof(Control))["Controls"], OldControls, _MBP.Controls);
                }
                catch (Exception ex)
                {
                    DisplayError(ex);
                    DT.Cancel();
                }
                finally
                {
                    DT.Commit();
                }
            }
        }

        #endregion
    }
}
